﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufInputControl.h"

namespace gnuf {
    class Info;
    
    class GNUF_BASE_EXPORT ITextControlHandler
        : public IInputControlHandler
    {
    public:
        virtual void onTextChanged(const std::wstring &) = 0;
    };
    
    class GNUF_BASE_EXPORT TextControlAdpatation
        : public InputControlAdaptation
    {
    protected:
        TextControlAdpatation();
        virtual ~TextControlAdpatation();

        //
        // Inherits from InputControlAdaptation...
        virtual void onVisibilityChanged(bool) override {}
        virtual void onSelectionChanged(bool) override {}
        
    public:
        virtual void onTextChanged(const std::wstring &) = 0;
    };

    class GNUF_BASE_EXPORT ITextControlObserver : public gcmp::WeakReferenceable
    {
    public:
        virtual bool onValidateText(const std::wstring & undeterminedText, std::wstring * hintIfInvalid) const { return true; }
    };
    
    class GNUF_BASE_EXPORT TextControl
        : public InputControl
    {
        CANNOT_COPY_OR_ASSIGN(TextControl)
    public:
        static const EItemType Type;
        TextControl(ITextControlHandler *, bool, gcmp::OwnerPtr< Info > &);
        virtual ~TextControl();
        
        inline bool readonly() const { return m_readonly; }
        inline const Info * info() const { return m_info.get(); }
        
        bool validateText(const std::wstring & undeterminedText, std::wstring * hintIfInvalid) const;
        void setText(const std::wstring &, const TextControlAdpatation * trigger = nullptr);

        void setObserver(ITextControlObserver * extension) { m_observer = extension; }
        const ITextControlObserver * observer() const {
            return (m_observer.IsValid() ? m_observer.Get() : nullptr);
        }

    private:
        const bool m_readonly;
        gcmp::OwnerPtr< Info > m_info;
        gcmp::WeakPtr<ITextControlObserver> m_observer;
    };
}
